package com.facetest.activity;

import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.util.Size;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;

import com.facetest.R;
import com.facetest.bean.FaceData;
import com.facetest.bean.ImageData;
import com.facetest.camera.CameraEngine;
import com.facetest.currencyview.OverlayView;
import com.facetest.encoder.BitmapEncoder;
import com.facetest.encoder.CircleEncoder;
import com.facetest.encoder.EncoderBus;
import com.facetest.encoder.RectEncoder;
import com.facetest.engine.CheckFaceEngine;
import com.seeta.sdk.util.SeetaHelper;
import com.seeta.sdk.util.SeetaUtil;
import com.tenginekit.Face;
import com.tenginekit.model.FaceDetectInfo;
import com.tenginekit.model.FaceLandmarkInfo;
import com.tenginekit.model.FaceLandmarkPoint;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class ClassifierActivity extends CameraActivity {

    private static final String TAG = "ClassifierActivity";

    private OverlayView trackingOverlay;

    @Override
    protected void initView() {
        photo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showEditDialog();
            }
        });
    }
    private Map<String,Bitmap> faceDataMap = new HashMap<>();
    private void showEditDialog(){
        final EditText inputServer = new EditText(ClassifierActivity.this);
        inputServer.setHint("请输入姓名");
        AlertDialog.Builder builder = new AlertDialog.Builder(ClassifierActivity.this);
        builder.setTitle("注册人脸").setView(inputServer)
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        cantStart = false;
                        dialog.dismiss();
                    }
                });
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                final String text = inputServer.getText().toString();
                photo.setDrawingCacheEnabled(true);
                final Bitmap bitmap=photo.getDrawingCache().copy(Bitmap.Config.ARGB_8888, true);
                photo.setDrawingCacheEnabled(false);
                if(bitmap!=null){
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            final FaceData faceData = SeetaUtil.getCompressFaceData(faceDataMap,bitmap);
                            if(faceData.getSim()>SeetaHelper.getInstance().SIMILARITY_VALUE){
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        Toast.makeText(ClassifierActivity.this,"添加失败!该人员已存在\n姓名:"+faceData.getName()+" 正确率:"+faceData.getSim(),Toast.LENGTH_SHORT).show();
                                    }
                                });
                            }else{
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        faceDataMap.put(text,bitmap);
                                        Toast.makeText(ClassifierActivity.this,"注册成功!",Toast.LENGTH_SHORT).show();
                                    }
                                });
                            }
                            cantStart = false;
                        }
                    }).start();
                }else{
                    Toast.makeText(ClassifierActivity.this,"注册失败!",Toast.LENGTH_SHORT).show();
                    cantStart = false;
                }
            }
        });
        builder.show();
        cantStart = true;
    }


    @Override
    protected int getLayoutId() {
        return R.layout.camera_connection_fragment;
    }

    @SuppressLint("NewApi")
    @Override
    protected Size getDesiredPreviewFrameSize() {
        return new Size(1280, 960);
    }

    public void Registe() {
        /**
         * canvas 绘制人脸框，人脸关键点
         * */
        EncoderBus.GetInstance().Registe(new BitmapEncoder(this));
        EncoderBus.GetInstance().Registe(new CircleEncoder(this));
        EncoderBus.GetInstance().Registe(new RectEncoder(this));
    }

    @Override
    public void onPreviewSizeChosen(final Size size) {
        Registe();
        EncoderBus.GetInstance().onSetFrameConfiguration(previewHeight, previewWidth);

        trackingOverlay = findViewById(R.id.facing_overlay);
        trackingOverlay.addCallback(new OverlayView.DrawCallback() {
            @Override
            public void drawCallback(final Canvas canvas) {
                EncoderBus.GetInstance().onDraw(canvas);
            }
        });
    }

    private boolean canStart = true;
    private boolean cantStart = false;
    @Override
    protected void processImage() {
        if (sensorEventUtil!= null) {
            getCameraBytes();
            int degree = CameraEngine.getInstance().getCameraOrientation(sensorEventUtil.orientation);
            /**
             * 设置旋转角
             */
            Face.Camera.setRotation(degree - 90, false, (int) CameraActivity.ScreenWidth, (int) CameraActivity.ScreenHeight);

            /**
             * 获取人脸信息
             */
            Face.FaceDetect faceDetect = Face.detect(mNV21Bytes);
            List<FaceDetectInfo> faceDetectInfos = new ArrayList<>();
            List<FaceLandmarkInfo> landmarkInfos = new ArrayList<>();
            if (faceDetect.getFaceCount() > 0) {
                faceDetectInfos = faceDetect.getDetectInfos();
                landmarkInfos = faceDetect.landmark2d();
            }


                Log.d("#####", "processImage: " + faceDetectInfos.size());
            if (faceDetectInfos != null && faceDetectInfos.size() > 0) {
                Rect[] face_rect = new Rect[faceDetectInfos.size()];

                List<List<FaceLandmarkPoint>> face_landmarks = new ArrayList<>();
                String text="";
                for (int i = 0; i < faceDetectInfos.size(); i++) {
                    Rect rect = new Rect();
                    rect = faceDetectInfos.get(i).asRect();
                    face_rect[i] = rect;
                    face_landmarks.add(landmarkInfos.get(i).landmarks);
                    FaceLandmarkInfo faceLandmarkInfo = landmarkInfos.get(i);

                    text +="第"+(i+1)+"张脸的位置:["+rect.left+","+rect.top+","+rect.right+","+rect.bottom+"] 宽:"+rect.width()+" 高:"+rect.height()+" 关键点:"+faceLandmarkInfo.landmarks.size()+"\n";
                    text+=" 偏转率:p"+faceLandmarkInfo.pitch+",y"+faceLandmarkInfo.yaw+",r"+faceLandmarkInfo.roll+"\n";
                    text+="左眼闭合:"+(faceLandmarkInfo.leftEyeClose>0.8?"是":"否")+",右眼闭合:"+(faceLandmarkInfo.rightEyeClose>0.8?"是":"否")+",嘴巴闭合:"+(faceLandmarkInfo.mouseClose>0.8?"是":"否")+",嘴巴张大:"+(faceLandmarkInfo.mouseOpenBig>0.8?"是":"否")+"\n";
                }

                if(isStart&&cantStart == false) {
                    toShowImage(face_rect, text);
                }
                //显示人脸框框
                EncoderBus.GetInstance().onProcessResults(face_rect);
                //显示人脸特征点
                EncoderBus.GetInstance().onProcessResults(face_landmarks);
                //检测动作
                CheckFaceEngine.getInstance().onCheckAction(landmarkInfos);
            }
        }

        runInBackground(new Runnable() {
            @Override
            public void run() {
                readyForNextImage();
                if (trackingOverlay!=null) {
                    trackingOverlay.postInvalidate();
                }
            }
        });
    }

    private boolean isStart = true;
    private void toShowImage(final Rect[] finalRect, final String finalText){
        isStart = false;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    if(finalRect.length>0){
                        Rect rects = finalRect[0];
                        Bitmap bitmap = nv21ToBitmap.nv21ToBitmap(mNV21Bytes,previewWidth,previewHeight,rects);
                        ImageData imageData = new ImageData();
                        imageData.setBitmap(bitmap);
                        imageData.setMsg(finalText);
                        Message message = new Message();
                        message.what=2;
                        message.obj = imageData;
                        handler.sendMessage(message);
                    }
                }catch (Exception e){

                }
                isStart = true;
            }
        }).start();
    }


    private void compareFace(final Bitmap bitmap){
        canStart = false;
        new Thread(new Runnable() {
            @Override
            public void run() {
                long time =System.currentTimeMillis();
                FaceData faceData = SeetaUtil.getCompressFaceData(faceDataMap,bitmap);
                Message message = new Message();
                message.what=1;
                message.obj = faceData;
                handler.sendMessage(message);
                long endtime =System.currentTimeMillis();
                Log.e("compare_face_use_time",endtime - time+"ms");
                canStart = true;
            }
        }).start();
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message message) {
            super.handleMessage(message);
            switch (message.what) {
                case 1:
                    FaceData faceData = (FaceData) message.obj;
                    if(faceData.getSim() >SeetaHelper.getInstance().SIMILARITY_VALUE){
                        rest.setText("识别结果:"+ faceData.getName() +"\n正确率:"+ faceData.getSim());
                    }else{
                        rest.setText("识别结果:人脸库中无该人员数据!\n点击缩略图添加");
                    }
                    break;
                case 2:
                    ImageData imageData = (ImageData)message.obj;
                    msg.setText(imageData.getMsg());
                    photo.setImageBitmap(imageData.getBitmap());
                    if(canStart){
                        compareFace(imageData.getBitmap());
                    }
                    break;
            }
        }
    };
    @Override
    public synchronized void onDestroy() {
        super.onDestroy();
        SeetaHelper.getInstance().destroy();
    }
}